import threading
from . import db


class UserManager:
    _users = dict()

    def __setitem__(self, key, value):
        assert isinstance(value, User)
        self._users[key] = value

    def __getitem__(self, item):
        if item not in self._users:
            return None

        return self._users[item]

    def __delitem__(self, key):
        if key in self._users:
            del self._users[key]

    def __len__(self):
        return len(self._users)

    def get_users(self, exclude=()):
        for u in db.get_users(exclude):
            user = User(u['username'])
            user['is_online'] = u['is_online']
            user['avatar'] = u['avatar']
            yield user

    # def mark_message(self, msg_id):
    #     return db.execute("update im_message set is_read=1 where id=%d" % msg_id)
    #
    # def save_message(self, sender, receiver, msg_type, message):
    #     cursor = db.get_connection().cursor()
    #     cursor.callproc("save_message", (sender, receiver, message, msg_type, "msgid"))
    #     cursor.execute("select @_save_message_4")
    #     msg = cursor.fetchone()
    #     cursor.close()
    #     return msg["@_save_message_4"]

    def get_user(self, username):
        user = User(username)
        properties = db.get_user(username)
        for p in properties:
            user[p] = properties[p]
        return user


class User:
    manager = UserManager()

    def __init__(self, user_id):
        self.user = user_id
        self._lock = threading.Lock()
        self._properties = {}
        self.manager[user_id] = self

    def __del__(self):
        del self.manager[self.user]

    def __setitem__(self, key, value):
        self._properties[key] = value
        self._update_user(key, value)

    def __getitem__(self, item):
        return self._properties[item]

    def _update_user(self, field, value):
        if isinstance(value, int):
            return db.execute("update im_user set %s=%d where username='%s'" % (field, value, self.user))
        else:
            return db.execute("update im_user set %s='%s' where username='%s'" % (field, str(value), self.user))

    def __str__(self):
        return self.user

    def __enter__(self):
        return self._lock.__enter__()

    def __exit__(self, exc_type, exc_val, exc_tb):
        return self._lock.__exit__(exc_type, exc_val, exc_tb)

    def __hash__(self):
        return self.user
